#include "jni_api.h"
#include <string.h>
#include <stdlib.h>
#include <typeinfo>

//jstring to char* 
std::string JniHelper::jstringTostring(JNIEnv* env, jstring jstr) 
{
	std::string result;
	char* buffer = NULL; 
	jclass clsstring = env->FindClass("java/lang/String"); 
	jstring encode = (env)->NewStringUTF("utf-8");
	jmethodID mid = (env)->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
	jbyteArray byteArray= (jbyteArray)(env)->CallObjectMethod(jstr, mid, encode);
	jsize len = (env)->GetArrayLength(byteArray);
	jbyte* bytes = (env)->GetByteArrayElements(byteArray, JNI_FALSE);
	if (len > 0) 
	{ 
		buffer = (char*)malloc(len + 1); 
		memcpy(buffer, bytes, len); 
		buffer[len] = 0;
		result = std::string(buffer);
	} 
	(env)->ReleaseByteArrayElements(byteArray, bytes, 0);

	if(buffer)
	{
		delete [] buffer;
		buffer = 0;
	}

	return result; 
}

//char* to jstring 
jstring JniHelper::stoJstring(JNIEnv* env, const char* str) 
{ 
	jclass cls = (env)->FindClass("java/lang/String");
	jmethodID mid = (env)->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
	jbyteArray bytes = (env)->NewByteArray(strlen(str));
	(env)->SetByteArrayRegion(bytes, 0, strlen(str), (jbyte*)str);
	jstring encoding = (env)->NewStringUTF("utf-8");
	return (jstring)(env)->NewObject(cls, mid, bytes, encoding);
}

jbyteArray JniHelper::bytesToJbyteArray(JNIEnv* env, unsigned char* data, int size)
{
	jbyteArray byteArray = (env)->NewByteArray(size);
	if(byteArray != 0)
	{
		(env)->SetByteArrayRegion(byteArray, 0, size, (jbyte*)data);
	}

	return byteArray;
}

void JniHelper::jbyteArrayToBytes(JNIEnv* env, jbyteArray byteArray, unsigned char* data, int size)
{
	(env)->GetByteArrayRegion(byteArray, 0, size, (jbyte*)data);
}

JniField::JniField(JNIEnv* env, const char* classname, jobject obj, const char* fieldname, const char* fieldsig)
{
	m_obj = 0;
	m_env = 0;
	m_fid = 0;

	if(env && classname && obj && fieldname && fieldsig)
	{
		m_obj = obj;
		m_env = env;
		jclass cls = (env)->FindClass(classname);

		if(cls != 0)
			m_fid = (env)->GetFieldID(cls, fieldname, fieldsig);
	}
}

bool JniField::isvalid()
{
	return m_fid && m_env && m_obj;
}

jint JniField::getInt()
{
	return (m_env)->GetIntField(m_obj, m_fid);
}

jobject JniField::getObject()
{
	return (m_env)->GetObjectField(m_obj, m_fid);
}

jchar JniField::getChar()
{
	return (m_env)->GetCharField(m_obj, m_fid);
}

jshort JniField::getShort()
{
	return (m_env)->GetShortField(m_obj, m_fid);
}

jboolean JniField::getBoolean()
{
	return (m_env)->GetBooleanField(m_obj, m_fid);
}